<template>
  <ProTable
    ref="tableRef"
    :fetchListApi="fetchListApi"
    :columns="columns"
    :row-selection="rowSelection"
    row-key="roleId"
    :onValuesChange="onValuesChange"
  >
    <template #toolbars>
      <Row class="w-full mr-3">
        <Col :span="16">
          <Space>
            <b-button icon="add" @click="onAdd" code="system:role:add"
              >新增</b-button
            >
            <b-button
              icon="delete"
              @click="onDelete(null)"
              :disabled="!selectKeys.length"
              code="system:role:remove"
              >删除</b-button
            >
          </Space>
        </Col>
        <Col :span="8" class="text-right content-center">
          <Space>
            <b-button icon="export" @click="onExport" code="system:role:export"
              >导出</b-button
            >
          </Space>
        </Col>
      </Row>
    </template>
    <template #bodyCell="{ column, record }">
      <template v-if="column.dataIndex === 'operation' && !record.admin">
        <b-button
          icon="edit"
          type="link"
          @click="() => onEdit(record)"
          code="system:role:edit"
          >编辑</b-button
        >
        <b-button
          icon="del"
          type="link"
          @click="() => onDelete(record)"
          code="system:role:remove"
          >删除</b-button
        >
      </template>
      <template v-if="column.dataIndex === 'status'">
        <Switch
          :checked="record.status"
          checked-value="0"
          un-checked-value="1"
          @change="(checked) => onChangeStatus(checked as string, record)"
        ></Switch>
      </template>
    </template>
  </ProTable>
  <FormModal :items="items">
    <template #menuIds="{ field, formState }">
      <SelectRole v-model:value="formState[field]" />
    </template>
  </FormModal>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue';
import { Col, Modal, Row, Space, Switch, message } from 'ant-design-vue';
import dayjs from 'dayjs';
import { ProFormProps } from '@/components/ProForm';
import { ProTable, ProTableProps } from '@/components/ProTable/index';
import { useFormModal } from '@/hooks/formModal';
import { download, listToEnum, listToOption } from '@/utils/utils';
import {
  createRole,
  deleteRole,
  exportRole,
  fetchRoleInfo,
  fetchRolePermission,
  fetchRoles,
  fetchSysNormalDisable,
  updateRole,
  updateRoleStatus,
} from '@/api/system';
import SelectRole from './components/SelectRole.vue';

const tableRef = ref();

const sysNormalDisableOptions = ref<Global.Option[]>([]);
const sysNormalDisableEnum = ref<Record<string, any>>([]);

const init = () => {
  fetchSysNormalDisable().then((res) => {
    sysNormalDisableOptions.value = listToOption(
      res.data,
      'dictLabel',
      'dictValue',
    ) as Global.Option[];
    sysNormalDisableEnum.value = listToEnum(res.data, 'dictValue', 'dictLabel');
  });
};

init();

const fetchListApi = async (_params: any) => {
  const { createTime = [], ...params } = _params;
  if (createTime.length) {
    const [beginTime, endTime] = createTime;
    Object.assign(params, {
      params: { beginTime, endTime },
    });
  }
  return fetchRoles({
    ...params,
  });
};

const selectKeys = ref<any[]>([]);
const rowSelection = ref<ProTableProps['rowSelection']>({
  onChange(values, all) {
    selectKeys.value = all as any[];
  },
});

const columns = computed<ProTableProps['columns']>(() => [
  // {
  //   title: '角色编号',
  //   dataIndex: 'roleId',
  //   align: 'center',
  //   hideInSearch: true,
  // },
  {
    title: '显示顺序',
    dataIndex: 'roleSort',
    align: 'center',
    hideInSearch: true,
  },
  {
    title: '角色名称',
    dataIndex: 'roleName',
    align: 'center',
  },
  {
    title: '权限字符',
    dataIndex: 'roleKey',
    align: 'center',
  },
  {
    title: '角色状态',
    dataIndex: 'status',
    align: 'center',
    valueEnum: {
      ...sysNormalDisableEnum.value,
    },
  },
  {
    title: '创建时间',
    dataIndex: 'createTime',
    align: 'center',
    isTime: true,
  },
  {
    title: '操作',
    dataIndex: 'operation',
    hideInSearch: true,
    align: 'center',
    fixed: 'right',
    width: 120,
  },
]);
const sleep = (cb) => {
  setTimeout(() => {
    cb();
  }, 500);
};

const onChangeStatus = (checked: string, record: any) => {
  const { roleName, roleId } = record;
  Modal.confirm({
    title: '系统提示',
    content: `确认要${checked === '1' ? '停用' : '启用'}${roleName}角色吗？`,
    centered: true,
    onOk: async () => {
      try {
        await updateRoleStatus({
          roleId,
          status: checked as '1' | '0',
        });
        tableRef.value.search();
      } catch (error) {
        const msg = (error as Error).message;
        if (msg !== '不允许操作超级管理员角色') {
          throw new Error(msg);
        }
        sleep(() => tableRef.value.refresh());
        message.error(msg);
      }
    },
  });
};

const items = computed<ProFormProps['items']>(() => [
  {
    label: '角色名称',
    type: 'input',
    field: 'roleName',
    rules: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
    props: {
      placeholder: '请输入角色名称',
    },
  },
  {
    label: '权限字符',
    type: 'input',
    field: 'roleKey',
    rules: [{ required: true, message: '请输入权限字符', trigger: 'blur' }],
    props: {
      placeholder: '请输入权限字符',
    },
  },
  {
    label: '角色顺序',
    type: 'number',
    field: 'roleSort',
    rules: [{ required: true, message: '请输入角色顺序', trigger: 'blur' }],
    props: {},
  },
  {
    label: '状态',
    type: 'radio',
    field: 'status',
    props: {
      options: sysNormalDisableOptions.value,
    },
  },
  {
    label: '菜单权限',
    type: 'input',
    field: 'menuIds',
    props: {
      autocomplete: 'off',
    },
  },
  {
    label: '备注',
    type: 'textarea',
    field: 'remark',
    props: {
      rows: 5,
      showCount: true,
    },
  },
]);

const { FormModal, open } = useFormModal({ size: 'small' });

const onAdd = async () => {
  open({
    title: '新增角色',
    defaultValue: {
      status: sysNormalDisableOptions.value[0].value,
      menuCheckStrictly: false,
    },
    serviceApi: async (params: any): Promise<any> => {
      if (!params.menuIds) params.menuIds = [];
      await createRole(params);
      sleep(() => tableRef.value.refresh());
    },
  });
};

const onEdit = async (record: any) => {
  const { roleId } = record;
  const [roleInfo, menuIds] = await Promise.all([
    fetchRoleInfo(roleId).then((res) => res.data),
    fetchRolePermission(roleId).then((res) => (res as any).checkedKeys),
  ]);

  open({
    title: '编辑角色',
    defaultValue: {
      ...roleInfo,
      menuIds,
    },
    serviceApi: async (params: any): Promise<any> => {
      await updateRole({
        ...params,
        roleId,
        menuCheckStrictly: false,
      });

      sleep(() => tableRef.value.refresh());
    },
  });
};

const onDelete = async (record: any) => {
  let ids = record
    ? record.roleId
    : selectKeys.value.map((item) => item.roleId).join(',');
  const roleNames = record
    ? record.roleName
    : selectKeys.value.map((item) => item.roleName).join(',');
  Modal.confirm({
    title: '系统提示',
    content: `确认要删除${roleNames}用户吗？`,
    centered: true,
    onOk: async () => {
      const res = await deleteRole(ids);
      if (res.code == 200) sleep(() => tableRef.value.refresh());
    },
  });
};

const searchParams = ref({});
const onValuesChange = (values: any) => {
  searchParams.value = Object.assign(searchParams.value, values);
};
const onExport = async () => {
  const res = await exportRole(searchParams.value);
  download(
    res as unknown as Blob,
    `data_${dayjs().format('YYYY-MM-DD HH:mm:ss')}.xlsx`,
  );
};
</script>
